﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using PracticeAzure.Website.Data;
using System.Web.Mvc;
using System.Web.Helpers;

namespace PracticeAzure.Website.Models
{
    public class CorrigendumEditViewModel
    {
        public enum CorrigendumAttachmentState
        {
            Original,
            Added,
            Deleted
        }

        public Corrigendum Corrigendum { get; set; }

        public IEnumerable<CorrigendumAttachmentWithState> ExistingAttachments { get; set; }

        public IEnumerable<HttpPostedFileBase> NewAttachments { get; set; }

        public class CorrigendumAttachmentWithState
        {
            public CorrigendumAttachment Attachment { get; set; }

            public CorrigendumAttachmentState State { get; set; }
        }

        public class ModelBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                // we will use the unvalidated form since we will encode the content by ourselves
                var unvalidatedValues = controllerContext.HttpContext.Request.Unvalidated();
                var forms = new Dictionary<string, string>();
                foreach (string key in unvalidatedValues.Form)
                {
                    forms.Add(key, unvalidatedValues.Form[key]);
                }
                var model = new CorrigendumEditViewModel();
                // bind the corrigendum property
                model.Corrigendum = new Corrigendum();
                // the title and body might be decoded which means its name will be changed
                // we dont need to encode the content since it come from the html editor
                model.Corrigendum.Title =forms
                    .Where(f => f.Key
                    .EndsWith("Title"))
                    .Select(f => f.Value)
                    .FirstOrDefault();
                model.Corrigendum.Body = forms
                    .Where(f => f.Key
                    .EndsWith("Body"))
                    .Select(f => f.Value)
                    .FirstOrDefault();
                model.Corrigendum.ID = long.Parse(forms["Corrigendum.ID"]);
                // validate the corrigendum itself
                if (string.IsNullOrWhiteSpace(model.Corrigendum.Title))
                {
                    bindingContext.ModelState.AddModelError("Corrigendum.Title", "标题不能为空");
                }
                if (string.IsNullOrWhiteSpace(model.Corrigendum.Body))
                {
                    bindingContext.ModelState.AddModelError("Corrigendum.Body", "内容不能为空");
                }
                // bind the existing attachments whether should be removed
                var attachments = new List<CorrigendumAttachmentWithState>();
                foreach (var attachment in forms.Where(f => f.Key.StartsWith("attachment-")))
                {
                    var attachmentId = long.Parse(attachment.Key.Split('-')[1]);
                    var state = string.Compare(attachment.Value, "true,false", true) == 0 ? CorrigendumAttachmentState.Deleted : CorrigendumAttachmentState.Original;
                    var filename = forms
                        .Where(f => string.Compare(f.Key, "blob-" + attachmentId.ToString()) == 0)
                        .Select(f => f.Value)
                        .FirstOrDefault();
                    attachments.Add(new CorrigendumAttachmentWithState()
                    {
                        Attachment = new CorrigendumAttachment()
                        {
                            ID = attachmentId,
                            URL = filename
                        },
                        State = state
                    });
                }
                model.ExistingAttachments = attachments;
                // bind the new attachments
                var files = new List<HttpPostedFileBase>();
                for (var i = 0; i < controllerContext.HttpContext.Request.Files.Count; i++)
                {
                    var file = controllerContext.HttpContext.Request.Files[i];
                    if (!string.IsNullOrWhiteSpace(file.FileName) && file.ContentLength > 0)
                    {
                        files.Add(file);
                    }
                }
                model.NewAttachments = files;
                return model;
            }
        }
    }
}